package com.hospital.interceptor;

import org.springframework.web.method.HandlerMethod;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 判断请求是否需要拦截
 *
 * @param "handler" 拦截器对象
 * @author yuhuan
 * @date 2022/3/23
 */
public class IsInterceptorToPreHandle {

    /**
     * 判断请求是否需要被拦截，会在处理的类或方法上寻找是否标有指定的注解，标有注解则拦截
     *
     * @param handler         当前被拦截的处理
     * @param annotationClass 具体的某个接口的class对象
     * @return 返回判断的结果，true表示该处理器会被拦截；false表示不拦截该处理的请求
     */
    public static boolean isInterceptor(Object handler, Class<? extends Annotation> annotationClass) {
        // 如果处理器不是期望的类型，不执行拦截
        if (!(handler instanceof HandlerMethod)) {
            return false;
        }
        // 处理器强转成封装类型的处理器（提供"getMethod"、"getBean"等一系列的方法）
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 返回此处理程序处理的方法
        Method method = handlerMethod.getMethod();
        // 处理的方法是否标记有指定的拦截注解
        boolean methodIsInterceptor = method.isAnnotationPresent(annotationClass);
        // 如果方法上没有定义拦截就检查类上面
        boolean beanIsInterceptor = false;
        if (!methodIsInterceptor) {
            Class<?> beanType = handlerMethod.getBeanType();
            beanIsInterceptor = beanType.isAnnotationPresent(annotationClass);
        }
        // 如果方法或者类上标记了拦截注解就进行拦截，否则就放行
        return methodIsInterceptor || beanIsInterceptor;
    }
}
